package com.wits.av;

import android.util.Log;

/**
 * Created by zhengboyuan on 2018-03-12.
 */

public class PsCaster implements MediaSink {

    public static final int 	PROTOCOL_UDP = JniPsCaster.PSCASTER_PROTOCOL_UDP;
    public static final int 	PROTOCOL_TCP = JniPsCaster.PSCASTER_PROTOCOL_TCP;
    public static final int 	PROTOCOL_RTP_UDP = JniPsCaster.PSCASTER_PROTOCOL_RTP_UDP;
    public static final int 	PROTOCOL_RTP_TCP = JniPsCaster.PSCASTER_PROTOCOL_RTP_TCP;

    public static final int 	PSCASTER_EVENT_CONNECTING = 0x11;   /// 连接中.
    public static final int 	PSCASTER_EVENT_CONNECTED = 0x12;    /// 连接成功.
    public static final int 	PSCASTER_EVENT_DISCONNECTED = 0x13; /// 断开连接了.

    static boolean inited = false;

    private static final String TAG = "jni";

    public static void init() {
        JniPsCaster.pscaster_init();
        inited = true;
    }

    public static void quit() {
        JniPsCaster.pscaster_quit();
        inited = false;
    }


    protected int handle = JniPsCaster.INVALID_HANDLE;
    protected PsCasterListener listener;

    public PsCaster() {
        if (!inited) {
            init();
        }
    }

    public boolean open(int protocol, int outPort, MFormat fmt) {
        Log.i(TAG, "PsCaster.open ");

        if (isOpen()) {
            close();
        }

        handle = JniPsCaster.pscaster_open(protocol, outPort, fmt);

        if (listener != null) {
            JniPsCaster.pscaster_setEventCallback(handle, listener);
        }

        Log.i(TAG, "PsCaster.open return " + handle);

        return (handle != JniPsCaster.INVALID_HANDLE);
    }

    public boolean open(int protocol, int outPort, MFormat fmt, int payload, int ssrc, boolean esMode) {
        Log.i(TAG, "PsCaster.open ");

        if (isOpen()) {
            close();
        }

        int es = esMode ? 1 : 0;
        handle = JniPsCaster.pscaster_openEx(protocol, outPort, fmt, payload, ssrc, es);

        if (listener != null) {
            JniPsCaster.pscaster_setEventCallback(handle, listener);
        }

        Log.i(TAG, "PsCaster.open return " + handle);

        return (handle != JniPsCaster.INVALID_HANDLE);
    }

    public void close() {
        Log.i(TAG, "PsCaster.close " + handle);

        if (handle != JniPsCaster.INVALID_HANDLE) {
            JniPsCaster.pscaster_close(handle);
            handle = JniPsCaster.INVALID_HANDLE;
        }

        Log.i(TAG, "PsCaster.close end");
    }

    public boolean isOpen() {
        return handle != JniPsCaster.INVALID_HANDLE;
    }

    public void addTarget(String ip, int port) {
        if (!isOpen()) {
            return;
        }

        JniPsCaster.pscaster_add_target(handle, ip, port);
    }

    public void removeTarget(String ip, int port) {
        if (!isOpen()) {
            return;
        }

        JniPsCaster.pscaster_remove_target(handle, ip, port);
    }

    public void removeAllTarget() {
        if (!isOpen()) {
            return;
        }

        JniPsCaster.pscaster_remove_all_target(handle);
    }


    private long lastPts = 0;

    public boolean write(MPacket pkt) {
        if (!isOpen()) {
            return false;
        }

        if (pkt.type == MediaType.MEDIA_TYPE_VIDEO) {
            if (pkt.pts < lastPts) {
                Log.w(TAG, "pkt pts decreased!");
            }
        }

        int rc = JniPsCaster.pscaster_write(handle, pkt);

        return (rc == 0);
    }

    public void setSendBufSize(int size) {
        if (size <= 0) {
            return;
        }

        JniPsCaster.pscaster_setSendBufSize(size);
    }


    @Override
    public void onMediaFormat(MFormat fmt) {
        // pass
    }

    @Override
    public void onMediaPacket(MPacket pkt) {
        write(pkt);
    }

    @Override
    public void onMediaEvent(int event) {
        // pass
    }


    public void setCasterEventCallback(PsCasterListener listener) {
        this.listener = listener;
        if (isOpen()) {
            JniPsCaster.pscaster_setEventCallback(handle, listener);
        }
    }

    /**
     * 启用/禁止TCP传输时的重连
     * @param enabled =true 表示允许.
     */
    public static void enableReconnect(boolean enabled) {
        JniPsCaster.pscaster_enableReconnect(enabled);
    }

}
